﻿using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace InfonavaEye.util
{
    public class FormAutoSize
    {
        public delegate void BeforeSizeChangeDelegate();
        public event BeforeSizeChangeDelegate beforeSizeChangeDelegate;

        public delegate void AfterSizeChangeDelegate(float wScale, float hScale);
        public event AfterSizeChangeDelegate afterSizeChangeDelegate;

        private int controlIndex = 0;

        //(1).声明结构,只记录窗体和其控件的初始位置和大小。  
        public struct controlRect
        {
            public int Left;
            public int Top;
            public int Width;
            public int Height;
        }
        //(2).声明 1个对象  
        //注意这里不能使用控件列表记录 List<Control> nCtrl;，因为控件的关联性，记录的始终是当前的大小。  
        public List<controlRect> oldCtrl = new List<controlRect>();

        /// <summary>
        /// 
        /// key：controlIndex
        /// </summary>
        public Dictionary<int, controlRect> controlDic = new Dictionary<int, controlRect>();

        //int ctrl_first = 0;  
        //(3). 创建两个函数  
        //(3.1)记录窗体和其控件的初始位置和大小,  
        public void controllInitializeSize(Form mForm)
        {
            // if (ctrl_first == 0)  
            {
                //  ctrl_first = 1;  
                controlRect cR;
                cR.Left = mForm.Left; cR.Top = mForm.Top; cR.Width = mForm.Width; cR.Height = mForm.Height;
                mForm.Tag = controlIndex;
                //oldCtrl.Add(cR);
                controlDic.Add(controlIndex, cR);
                measureSize(mForm);
            }
            mForm.WindowState = (System.Windows.Forms.FormWindowState)(2);//记录完控件的初始位置和大小后，再最大化  
            //0 - Normalize , 1 - Minimize,2- Maximize  
        }

        private void measureSize(Control control)
        {
            foreach (Control c in control.Controls)
            {
                controlIndex++;
                controlRect objCtrl;
                objCtrl.Left = c.Left; objCtrl.Top = c.Top; objCtrl.Width = c.Width; objCtrl.Height = c.Height;
                c.Tag = controlIndex;
                //oldCtrl.Add(objCtrl);
                controlDic.Add(controlIndex, objCtrl);
                if (c.Controls != null && c.Controls.Count > 0)
                {
                    measureSize(c);
                }
            }
        }

        //(3.2)控件自适应大小,  
        public void controlAutoSize(Form mForm)
        {
            if (beforeSizeChangeDelegate != null)
            {
                beforeSizeChangeDelegate.Invoke();
            }

            controlRect objCtrl = controlDic[(int)mForm.Tag];
            float wScale = (float)mForm.Width / (float)objCtrl.Width;//新旧窗体之间的比例，与最早的旧窗体  
            float hScale = (float)mForm.Height / (float)objCtrl.Height;//.Height;  
            resetSize(mForm, wScale, hScale);

            if (afterSizeChangeDelegate != null)
            {
                afterSizeChangeDelegate.Invoke(wScale, hScale);
            }
        }

        private void resetSize(Control control, float wScale, float hScale)
        {
            int ctrLeft0, ctrTop0, ctrWidth0, ctrHeight0;

            foreach (Control c in control.Controls)
            {
                if (controlDic.ContainsKey((int)c.Tag))
                {
                    controlRect objCtrl = controlDic[(int)c.Tag];
                    ctrLeft0 = objCtrl.Left;
                    ctrTop0 = objCtrl.Top;
                    ctrWidth0 = objCtrl.Width;
                    ctrHeight0 = objCtrl.Height;
                   
                    if (c is Button)
                    {
                        c.Width = (int)(ctrWidth0);
                        c.Height = (int)(ctrHeight0);
                        c.Left = (int)((ctrLeft0) * wScale) + ((int)((ctrWidth0) * wScale) - ctrWidth0);
                        c.Top = (int)((ctrTop0) * hScale) + ((int)((ctrHeight0) * hScale) - ctrHeight0);
                    }
                    else {
                        c.Left = (int)((ctrLeft0) * wScale);
                        c.Top = (int)((ctrTop0) * hScale);
                        c.Width = (int)(ctrWidth0 * wScale);
                        c.Height = (int)(ctrHeight0 * hScale);
                    }
                }

                if (c.Controls != null && c.Controls.Count > 0)
                {
                    resetSize(c, wScale, hScale);
                }

            }
        }
    }
}
